jQuery.noConflict(); // kein aerger mit dem jquery namespace

// Thanks for this code snippet from http://www.tutorials.de/
var HTTP_GET_VARS = new Array();
var strGET = document.location.search.substr(1, document.location.search.length);
if (strGET != '') {
    var gArr = strGET.split('&');
    var i;
    for (i = 0; i < gArr.length; ++i) {
        var v = '';var vArr = gArr[i].split('=');
        if (vArr.length > 1) { v = vArr[1]; }
        HTTP_GET_VARS[unescape(vArr[0])] = unescape(v);
    }
}

function GET(v) {
    if (!HTTP_GET_VARS[v]) { return 'undefined'; }
    return HTTP_GET_VARS[v];
}


var total_header = 0; // # Header
var total_params = 0; // # Parameter
var total_cookies = 0;// # Cookies

var blocking_mode_updated = false; // indicates that blocking mode was temp. switched off in order to send a request with Request Forge

function id(id) {

    return document.getElementById(id);
}

function bg() {

    return chrome.extension.getBackgroundPage();
}

function setRefHtml() {
    bg().reference_html = id("response_html_source").value;
    id("response_html_diff_div").innerHTML = getDiffString();
}

function getXSSVectorArray() {
    var vectors = [];
    //console.log(frames["xss_vectors_iframe"].document.getElementsByTagName("textarea").length);
    var textareas = frames["xss_vectors_iframe"].document.getElementsByTagName("textarea");
    var i;
    for(i = 0; i < textareas.length; i++) {
        vectors.push(textareas[i].value);
        //console.log(textareas[i].value);
    }
    return vectors;
}

function getSQLVectorArray() {
    var vectors = [];
    //console.log(frames["sql_vectors_iframe"].document.getElementsByTagName("textarea").length);
    var textareas = frames["sql_vectors_iframe"].document.getElementsByTagName("textarea");
    var i;
    for(i = 0; i < textareas.length; i++) {
        vectors.push(textareas[i].value);
        //console.log(textareas[i].value);
    }
    return vectors;
}

function getParamAutoCompleteElements(param_name) {
    /********************************************************************************************************************
    * Search in bg().requests for other requests that match this url and parameter name with a different parameter value
    * Use these values to autocomplete a input field for a the parameter value
    * return array of Strings, which represent a possible autocomplete value
    ********************************************************************************************************************/
    var elements = [];
    var url = id("request_url").value;
    var i,j;

    for (i = 0; i < bg().requests.length; i++) {
        if( url == bg().requests[i].url.toString()) {
            for(j = 0; j < bg().requests[i].params.length; j++) {
                if( param_name == bg().requests[i].params[j].name.toString()
                    && jQuery.inArray(bg().requests[i].params[j].value.toString(), elements) == -1 ) {
                            
                    elements.push(bg().requests[i].params[j].value.toString());
                }
            }
        }
    }
    return elements;
}

function getHeaderAutoCompleteElements(header_name) {
    var elements = [];
    var url = id("request_url").value;
    var i,j;

    for (i = 0; i < bg().requests.length; i++) {
        if(url == bg().requests[i].url.toString()) {
            for(j = 0; j < bg().requests[i].header.length; j++) {
                if(bg().requests[i].header[j].name.toString() == "Cookie") {
                    continue;
                }
                else if(header_name == bg().requests[i].header[j].name.toString()
                        && jQuery.inArray(bg().requests[i].header[j].value.toString(), elements) == -1 ) {
                            
                    elements.push(bg().requests[i].header[j].value.toString());
                }
            }
        }
    }
    return elements;
}

function getSessionMenuHandler(sessionid_name) {
    handler = function showSessionIdMenu() {
        var url = id("request_url").value;
        var method = id("request_method").value;
        var param_arr = getEncodedParamArrayFromTampered();
        var header_arr = getHeaderArrayFromTampered();
        bg().spawningRequestDetails = {
        	"url": url,
        	"method": method,
        	"header_arr": header_arr,
        	"param_arr": param_arr,
        	"sessionidname": sessionid_name
        };
        
        /*open_url_str =  "SessionIdMenu.html?url=" + encodeURIComponent(url) 
                        + "&method=" + encodeURIComponent(method)
                        + "&headers" + encodeURIComponent((JSON.stringify(getHeaderArrayFromTampered)));
                        + "&params=" + encodeURIComponent(JSON.stringify(param_arr))
                        + "&sessionidname=" + encodeURIComponent(sessionid_name);
			*/
        var newWin=window.open("SessionIdMenu.html", "SessionID Menu", "height=800, width=1024,toolbar=no,scrollbars=yes,menubar=no,location=no");
                
    }
    return handler;
}

function getDiffString() {
    /****************************************************************************
    * Calculate Myer's diff algorithm for reference-html and shown html response
    *****************************************************************************/
                
    var dmp =   new diff_match_patch(); // set diff_match_patch.Diff_Timeout to a higher value to get more precise resulsts!?
    var t1 = bg().reference_html;
    var t2 = id("response_html_source").value;
    if(t1 == null) {
        return "<font color = 'green' size = '+1'>Please specify a standard response</font>";
    }
    var diff_raw = dmp.diff_main(t1,t2);
    var str = "";
    if(diff_raw.length > 1) {
        str = "<font color = 'red' size = '+1'>" + diff_raw.length + " differences found:</font><br/><br/>";
                    
    }
    else {
        str = "<font color = 'green' size = '+1'>No differences found:</font><br/><br/>";
    }
    dmp.diff_cleanupSemantic(diff_raw); 
    var html_str = dmp.diff_prettyHtml(diff_raw); // Diese Funktion ueberschreiben damit Zeilenangaben moeglich sind?
                
    return (str + html_str);
    /*var newWin=window.open("about:blank", "Diff String View", "height=800, width=600,toolbar=no,scrollbars=yes,menubar=no,location=no");
    newWin.document.write(html_str);
    */
}

function injectNullByte(string) {
	console.log("Looking for null byte intjection in: " + string);	
	return string.replace(/\$NULL/g, String.fromCharCode(0));
}

function getEncodedParameter(i) {
	/************************************************************************************************
	* URLencodes the parameter	number i if checkbox is checked, leaves the parameter unencoded else
	* If checkbox with id "use_null_byte_check" is checked, the function inserts the null byte for
	* 	each occurence of $NULL in a parameter name or value
	* returns object {name: p_name, value: p_value}
	* this object represents parameter #i with the corresponding encoding
	*************************************************************************************************/	
	var request = parseInt(GET("r"));
	
	var param = {
		name: "",
		value: ""
	};
	
	var tmp = id("param_name_" + request + "_" + i).value;
	if(id("use_null_byte_check").checked) {
		tmp = injectNullByte(tmp);
		//console.log("Injected null byte: " + tmp);
   } 
   
	if(id("param_name_" + request + "_" + i + "_URLencoding").checked) {	   	
    	param.name = encodeURIComponent(tmp);
    	//console.log("URLencoding...");
   }
   else {
   	param.name = tmp;
   }
   
   tmp = id("param_value_" + request + "_" + i).value;
	if(id("use_null_byte_check").checked) {
		tmp = injectNullByte(tmp);
		//console.log("Injecting null byte into " + tmp);
   }
    
   if(id("param_value_" + request + "_" + i + "_URLencoding").checked) {		    	
    	param.value = encodeURIComponent(tmp);
    	//console.log("URLencoding...");
   }
   else {
   	param.value = tmp;
   }
   
   return param;
}

function getEncodedParamStringFromTampered() {
    var request = parseInt(GET("r"));
    var param_str = "";
    var parameter;
    var begin = true;
    var i;
    for (i = 0; i < total_params; i++) {
        if(jQuery.trim(id("param_name_" + request + "_" + i).value) != "") {
            if (!begin) {
                // am anfang kein & setzen...
                param_str += "&";
            }
            else {
                begin = false;
            }
            
            parameter = getEncodedParameter(i);
            param_str += parameter.name + "=" + parameter.value;
        }
    }
    console.log("Used this encoding: " + param_str);
    return param_str;
}

function getParamArrayFromTampered() {
	/******************************************************************************************
	* Use this function to save (unencoded) request parameters in the background datastructure	
	******************************************************************************************/    
    var request = GET("r");
    var arr = [];
    var i;
    for (i = 0; i < total_params; i++) {
        if(jQuery.trim(id("param_name_" + request + "_" + i).value) != "") {    
            arr.push({name: id("param_name_" + request + "_" + i).value, value: id("param_value_" + request + "_" + i).value });
        }
    }
    console.log("Saving: " + JSON.stringify(arr));
    return arr;
}

function getEncodedParamArrayFromTampered() {
	/****************************************************************************************************
	* Use this function to submit a request via the OpenResponseInNewTab feature or via session spawning
	*****************************************************************************************************/
    var request = GET("r");
	 var parameter;    
    var arr = [];
    var i;
    for (i = 0; i < total_params; i++) {
        if(jQuery.trim(id("param_name_" + request + "_" + i).value) != "") {    
				parameter = getEncodedParameter(i);        
            arr.push({name: parameter.name, value: parameter.value }); // copy into array
        }
    }
    console.log("Saving: " + JSON.stringify(arr));
    return arr;
}


function getHeaderArrayFromTampered() {
    var request = GET("r");
    var arr = [];
    var i;
    for (i = 0; i < total_header; i++) {
        if(jQuery.trim(id("header_header_" + request + "_" + i).value) != "") {
            if ( jQuery.trim(id("header_header_" + request + "_" + i).value) == "Cookie"){
                arr.push({name: "Cookie", value:getCookieStringFromInput()});
            }
            else {
            	 var name = jQuery.trim(id("header_header_" + request + "_" + i).value);
            	 var value = jQuery.trim(id("header_content_" + request + "_" + i).value);
            	 
            	 if(id("use_null_byte_check").checked) {
							name = injectNullByte(name);
							value = injectNullByte(value);                				
                }
                arr.push({"name": name,"value": value});
            }
        }
    }
    return arr;
}

function getDeleteCookieHandler(i) {
    var handler = function() {
        id("cookie_" + i + "_name").value = "";
        id("cookie_" + i + "_value").value = "";
        id("cookie_row_" + i).style.display = "none";
    };

    return handler;
}

function getCookieAutoCompleteElements(cookie_name) {
    var elements = [];
    var url = id("request_url").value;
    var i,j,k;
    var cookies;
    //console.log("Searching AutoCompleteElements for cookie " + cookie_name);
    for(i = 0; i < bg().requests.length; i++) {
        if(url == bg().requests[i].url.toString()) {
            for(j = 0; j < bg().requests[i].header.length; j++) {
                if(bg().requests[i].header[j].name.toString() == "Cookie") {
                    cookies = getCookieArrFromString(bg().requests[i].header[j].value.toString());
                    for(k = 0; k < cookies.length; k++) {
                        if( jQuery.trim(cookie_name) == jQuery.trim(cookies[k].name.toString())
                            && jQuery.inArray(cookies[k].value.toString(), elements) == -1 ) {
                            elements.push(cookies[k].value.toString());
                        }
                    }
                }
            }   
        }
    }
    return elements;   
}

function getCookieArrFromString(cookie_str) {
    /*********************************************************************************************
    * builds an array with Cookie ojects from string notation of cookies as given in Cookie-header
    * returns array of form [{name: cookie_name, value: cookie_value}, ....]
    **********************************************************************************************/
    var cookie_arr = [];
    var cookies = cookie_str.split(";");
                    
    if(cookies.length == 0) {
        return cookie_arr;
    }

    var i;
    var j;
    var cookie_name;
    var cookie_value;

    for(i = 0; i < cookies.length; i++) {
        // cleanup, deleting cookies with chrome.cookies.remove can produce a string like "; ;name_1=value_1; ..."
        if(jQuery.trim(cookies[i].toString()) == "") {
            cookies.splice(i,1);
        }
    }

    for(i = 0; i < cookies.length; i++) {
        j = cookies[i].toString().indexOf("=");
        if( j == -1 || j == 0 ) {
            alert("Malformed Cookie: " + cookies[i].toString());
            continue;
        }
        cookie_name = jQuery.trim(cookies[i].toString().substring(0,j));
        cookie_value = "";
        if( j < cookies[i].toString().length -1 ) {
            cookie_value = jQuery.trim(cookies[i].toString().substring(j+1,cookies[i].toString().length));
        }
        cookie_arr.push({name: cookie_name,value: cookie_value});
    }

    return cookie_arr;
}

function getCookieAutoCompleteHandler(i) {
    var handler = function () {
        var param_name = id("cookie_" + i + "_name").value;
        var xss_vectors;
        var sql_vectors;
        var elements = getCookieAutoCompleteElements(param_name);
        if (id("make_suggestions_xss_check").checked == 1) {
            xss_vectors = getXSSVectorArray();
            elements = elements.concat(xss_vectors);
        }
        if (id("make_suggestions_sql_check").checked == 1) {
            sql_vectors = getSQLVectorArray();
            elements = elements.concat(sql_vectors);
        }
        jQuery("input#cookie_" + i + "_value").autocomplete({ source: elements });
    }
    return handler;
}

function buildCookieEditor(cookie_str) {
    var cookies = getCookieArrFromString(cookie_str);
    var tr, td, input, cookie_name, cookie_value;
    var i,k;
                
    total_cookies = cookies.length;


    for(i = 0; i < cookies.length; i++) {
                    
        cookie_name = cookies[i].name;
        cookie_value = cookies[i].value;

        tr = document.createElement("tr");
        tr.id = "cookie_row_" + i;
        td = document.createElement("td");
        input = document.createElement("input");
        input.type = "hidden"; // speichere originalen Cookie Name um dieses entfernen zu koennen
        input.id = "cookie_" + i + "_orig_name";
   
        input.value = cookie_name;
        td.appendChild(input);
        input = document.createElement("input");
        input.type = "text";
        input.id = "cookie_" + i + "_name";
        input.value = cookie_name;
        td.appendChild(input);
        tr.appendChild(td);
        
        td = document.createElement("td");
	     input = document.createElement("input");
	     input.type = "checkbox";
	     input.id = "cookie_" + i + "_name_URLencoding";
	     input.name = "cookie_" + i + "_name_URLencoding";
	     input.checked = "";
	     td.appendChild(input);
	     tr.appendChild(td);	 

        td = document.createElement("td");
        input = document.createElement("input");
        input.id = "cookie_" + i + "_value";
        input.value = cookie_value;
        input.setAttribute("style", "width:400px");
        input.onfocus = getCookieAutoCompleteHandler(i);
        td.appendChild(input);
        tr.appendChild(td);
        
        td = document.createElement("td");
	     input = document.createElement("input");
	     input.type = "checkbox";
	     input.id = "cookie_" + i + "_value_URLencoding";
	     input.name = "cookie_" + i + "_value_URLencoding";
	     input.checked = "";
	     td.appendChild(input);
	     tr.appendChild(td); 

        td = document.createElement("td");
        input = document.createElement("input");
        input.type = "image";
        input.src = "Delete.png";
        input.alt = "Delete";
        input.onclick = getDeleteCookieHandler(i);
        td.appendChild(input);
        tr.appendChild(td);
        id("table_r_cookie").appendChild(tr);

        // cookie_name auf sessionids untersuchen, gegen alle bekannten sessionID Namen vergleichen
        // falls SessionID gefunden, gebe zus. zeile in Tabelle aus um sessionID menu anzuzeigen
                    
        for (k = 0; k < bg().known_sessionid_names.length; k++) {
            if ( bg().known_sessionid_names[k].toString() == cookie_name) {
                //alert("Found a known sessionid name in cookie: " + known_sessionid_names[k]);
                var warning_id = bg().requests[parseInt(GET('r'))].session_warning;
                if(warning_id) {
                    var font = document.createElement("font");
                    font.color = "red";
                    font.innerHTML = "WARNING: Session " + bg().sessions[warning_id].name + " was used in subsequent HTTPS requests and is now send via HTTP<br/>";
                    input = document.createElement("textarea");
                    input.setAttribute("style", "width:630px;height:50px;");
                    input.readOnly = true;
                    var c;
                    for(c = 0; c < bg().sessions[warning_id].urls.length; c++) {
                        input.value += bg().sessions[warning_id].urls[c].toString()+"\r\n";
                    }
                    id("sessionid_messages").appendChild(font);
                    id("sessionid_messages").appendChild(input);
                    id("sessionid_messages").appendChild(document.createElement("br"));
                }
                
                input = document.createElement("input");
                input.type = "button";
                input.value = "Session ID Spawning " + bg().known_sessionid_names[k].toString();
                input.onclick = getSessionMenuHandler(bg().known_sessionid_names[k].toString());
                id("sessionid_messages").appendChild(input);
                id("sessionid_messages").appendChild(document.createElement("br"));
            }
                        
        }
    }
    id("table_r_cookie").style.display = "block";
                
}

function setCookieFromInput() {
    /*************************************************************
        * set Cookie according to data in table id("table_r_cookie")
        ************************************************************/
                
    var old_name, name, value;
    var url = id("request_url").value;
    var i;

    if(total_cookies == 0) {
        return;
    }

                
    for(i = 0; i < total_cookies; i++) {
        old_name    = jQuery.trim(id("cookie_" + i + "_orig_name").value);
        name        = jQuery.trim(id("cookie_" + i + "_name").value);
        value       = jQuery.trim(id("cookie_" + i + "_value").value);
        
        if(id("use_null_byte_check").checked) {
				name = injectNullByte(name);
				value = injectNullByte(value);            
        }
        
        if(id("cookie_" + i + "_name_URLencoding").checked) {
        		name = encodeURIComponent(name);	
        }
        if(id("cookie_" + i + "_value_URLencoding").checked) {
        		value = encodeURIComponent(value);	
        }
            
        if(old_name == "" && name!= "") {
            // set a new Cookie
            console.log("Setting new cookie: " + name);
            
            chrome.cookies.set({url:url, name:name, value:value}, function(details) {
                if(details == null) {
                    alert("Couldn`t set Cookie with name: " + old_name);
                }
            });
        }else if(old_name != "" && name == "") {
            // delete cookie
            console.log("Deleting cookie: " + old_name);
            chrome.cookies.remove({url:url, name:old_name}, function(details) {
                if(details == null) {
                    alert("Couldn`t remove Cookie with name: " + old_name);
                }
            });
        }else if(old_name != "" && name != "" && old_name != name) {
            // delete cookie with old_name, set Cookie with name
            console.log("Replacing cookie " + old_name + " with " + name);
            chrome.cookies.remove({url:url, name:old_name}, function(details) {
                if(details == null) {
                    alert("Couldn`t remove Cookie with name: " + old_name);
                }
            });
            
            
            chrome.cookies.set({url:url, name:name, value:value}, function(details) {
                if(details == null) {
                    alert("Couldn`t set Cookie with name: " + old_name);
                }
            });
        }
        else {
            console.log("Overwriting cookie " + old_name);
            console.log("New cookie value: " + value);
            
            chrome.cookies.set({url:url, name:name, value:value}, function(details) {
                if(details == null) {
                    alert("Couldn`t set Cookie with name: " + old_name);
                }
                else {
                	console.log("New stored cookie value : " + details.value);	
                }
            });
            /*chrome.cookies.get({url:url, name:name}, function(cookie) {
                if(cookie == null || cookie.value != value) {
                    // update Cookie
                    console.log("Old cookie value: " + cookie.value);
                    console.log("New cookie value: " + value);
                    chrome.cookies.set({url:url, name:name, value:value}, function(details) {
                        if(details == null) {
                            alert("Couldn`t set Cookie with name: " + old_name);
                        }
                    });
                }
            });*/
        }
    }
}

function getCookieStringFromInput() {
    var cookie_str = "";
    var i;
    var name;
    var value;

    for(i = 0; i < total_cookies; i++) {
        name = jQuery.trim(id("cookie_" + i + "_name").value);
        value = jQuery.trim(id("cookie_" + i + "_value").value);
        
		  if(id("use_null_byte_check").checked) {
				name = injectNullByte(name);
				value = injectNullByte(value);            
        }
        
        if(id("cookie_" + i + "_name_URLencoding").checked) {
        		name = encodeURIComponent(name);	
        }
        if(id("cookie_" + i + "_value_URLencoding").checked) {
        		value = encodeURIComponent(value);	
        }      
        
        if(name != "") {
            cookie_str += name + "=" + value + ";";
        }
    }
    return cookie_str;
}


function registerRequestHeaders(header_arr) {
		 /************************************************************************************		  
		  * Workaround to set headers that are not editable via XHR:
		  * set variable tamperedHeaders in background script to contain an array of headers
		  * this is a signal that headers should be modified for the next request.
		  * header_arr should be null to signal that headers should  not be modified.
		  *************************************************************************************/
		  bg().tamperedHeaders = header_arr;
        
}


function getHtmlResponseFromTampered() {
    /*****************************************************************************************************************************************
    * nehme parameter von input feldern und baue einen serialisierten string so dass dieser in url oder in post anfrage verwendet werden kann
    * sende neue anfrage und speichere ein request objekt in der background datenstruktur
    ******************************************************************************************************************************************/

    var request = GET("r"); // index des requests in background datenstruktur
    var request_obj = {}; // neues request objekt kommt in die background datenstruktur
    var url = id("request_url").value;
    var method = id("request_method").value;
    var header, content, param, value;
    var param_str;

    xmlhttp = new window.XMLHttpRequest();

    param_str = getEncodedParamStringFromTampered();

    if (method.toUpperCase() == "GET") {
        url += ("?" + param_str);
    }


    xmlhttp.open(method, url,true);
                
    var header_arr = getHeaderArrayFromTampered();
    var i;
    for (i = 0; i < header_arr.length; i++) {
                    
        if(header_arr[i].name.toString() == "Cookie") {
            setCookieFromInput();
        }
        else { 

				// set request headers via XHR. Those that are not editable in XHR are treated via the setRequestHeaderHandler() call by chrome.webRequest API
            header = header_arr[i].name.toString();
            content = header_arr[i].value.toString();          
            xmlhttp.setRequestHeader(header, content);

        }

    }
    registerRequestHeaders(header_arr);

    xmlhttp.onreadystatechange = function () {
        if (this.readyState == 4) { // TODO: Fehlerbehandlung falls response Error
				unsetWaitingBox();				
				checkBlockingModeAfterSend();
				registerRequestHeaders(null);         
            if(     id("response_html_source_div").style.display == "none"
                &&  id("response_iframe_div").style.display == "none"
                &&  id("response_header_div").style.display == "none"
                &&  id("response_html_diff_div").style.display == "none") {

                // Erste anfrage, erste response
                id("response_html_source_div").style.display = "block";
                id("response_html_source").style.width = "100%";
                id("response_html_source").style.height = "100%";
                id("response_html_source").className = "lined";
                id("response_html_source").value = xmlhttp.responseText;
                id("response_header_textarea").value = xmlhttp.getAllResponseHeaders();
                id("response_header_textarea").style.width = "100%";
                id("response_header_textarea").style.height = "100%";
                jQuery(".lined").linedtextarea();
                var html_str = id("response_html_source").value;
                id("response_iframe").setAttribute("sandbox", ""); // no exceptions for restrictions
                id("response_iframe").contentDocument.write(html_str);
                id("response_iframe").style.width = "100%";
                id("response_iframe").style.height = "100%";
                id("response_html_diff_div").innerHTML = getDiffString();
                id("response_radios").style.display = "block";
                jQuery("#response_radios").buttonset();
            }
            else {
                // nicht nochmal linedtextarea() aufrufen
                            
                id("response_html_source").value = xmlhttp.responseText;
                id("response_header_textarea").value = xmlhttp.getAllResponseHeaders();
                // create a new iframe because we cannot rewrite document of the old iframe, same origin policy
                id("response_iframe_div").innerHTML = "";
                var iframe  = document.createElement("iframe");
                iframe.id = "response_iframe";
                id("response_iframe_div").appendChild(iframe);
                var html_str = id("response_html_source").value;
                id("response_iframe").setAttribute("sandbox", ""); // no exceptions for restrictions 
                id("response_iframe").setAttribute("style", "width:100%;height:100%;");
                id("response_iframe").contentDocument.write(html_str);
                id("response_html_diff_div").innerHTML = getDiffString();
                // if we dont execute the following two lines content gets not rendered right?!
            }
            id("set_reference_button").style.display = "inline";
            id("set_reference_button").onclick = setRefHtml;

            window.location.hash = "";
            window.location.hash = "#response_radios";
        }
    };

    if (method.toUpperCase() == "POST") {
        var request_data = { url: url, data: param_str,method :method, submission: "ForgePanel XMLHttpRequest" };
                    
        chrome.extension.sendRequest(request_data); // Request does not get captured??
        console.log("Sending request");
		  checkBlockingModeBeforeSend();        
        xmlhttp.send(param_str);
        setWaitingBox();

    }
    else {
        console.log("Sending request");
		  checkBlockingModeBeforeSend();        
        xmlhttp.send(null);
        setWaitingBox();
    }
    //saveRequest();// workaround
    
}

function setWaitingBox() {
	// set a little animation to show Request Forge is waiting for a response
	id("awaiting_response_img").src = "Loading.gif";
	id("awaiting_response_img").style.display = "block";
	id("show_response_button").style.display = "none";
}

function unsetWaitingBox(){
	// unset the little animation to show Request Forge is waiting for a response
	id("awaiting_response_img").src = "";	
	id("awaiting_response_img").style.display = "none";
	id("show_response_button").style.display = "inline";
}

function checkBlockingModeBeforeSend() {
	// Disable blocking mode in background script so RF does not block its own request
	// re-enable blocking mode in onreadystateshange event by calling checkBlockingModeAfterSend()
	if (bg().blocking_mode) {
		bg().blocking_mode = false;
		blocking_mode_updated = true;
		console.log("Disabling Blocking");
	}   
}

function checkBlockingModeAfterSend() {
	// re-enable blocking mode in background script after request is sent	
	if(blocking_mode_updated) {
		bg().blocking_mode = true; 
		blocking_mode_updated = false;
		console.log("Re-enabling Blocking");
   }
}

function saveRequest() {
    /******************************************************************************************************************************************************
    * WORKAROUND:
    * Chrome does not capture the above requests via our onBeforeSendHeaders-Listener in background.html when "blocking" feature is contained in manifest.
    * (without "blocking" the request is captured correctly) So we need to save the request manually to the background-datastructure "requests".
    * The following lines should be removed if in future versions chrome captures this request correctly and the request is saved twice.
    ******************************************************************************************************************************************************/
    // set Cookie Header if there are Cookies
    var header_arr = getHeaderArrayFromTampered();
    for(i = 0; i < header_arr.length; i++) {
        if(header_arr[i].name.toString() == "Cookie") {
            header_arr[i].value = getCookieStringFromInput();
        }
    }
    // get Parameter Array for the datastructure
    var param_arr = getParamArrayFromTampered();
    // build object that gets saved in background datastructure
    var request = {
        params: param_arr,
        header: header_arr,
        url: id("request_url").value,
        method: id("request_method").value
    };
    // save
    //console.log(JSON.stringify(request));
    bg().requests.push(request);
    
}

function isUserAgentHeader(header_name) {
    var i;
    for(i = 0; i < bg().user_agent_header.length; i++) {
        if(header_name.toString() == bg().user_agent_header[i].toString()) {
            return true;
        }
    }
    return false;
}

function userAgentHeaderMsg() {
    alert("XMLHttpRequest ignores this header.");
    this.onclick = ""; // say this only once
}

// Functions defined, DOM processing goes here
window.onload = function  () {
    // called by jQuery.ready()
    id("fuzzing_link").href = chrome.extension.getURL("Fuzzer.html") + "?r=" + parseInt(GET('r'));

    if (bg().requests[parseInt(GET('r'))].submission != undefined) {
        id("submission_via").innerHTML = ("Submission via " + bg().requests[parseInt(GET('r'))].submission);
    }

    var j;
    var tr, td, input, button, name, value;
    var req = parseInt(GET('r')); // der index des gewuenschten requests im array



    id("request_url").value = bg().requests[req].url;
    id("request_url").size = bg().requests[req].url.length;

    id("save_url_captures_button").onclick = function () {
        open_url_str = "Dump.html?r="+req;
        var newWin = window.open(open_url_str, "SessionID Menu", "height=800, width=1024,toolbar=no,scrollbars=yes,menubar=no,location=no");
    };

    function getDelHeaderHandler(j) {
        // TODO: improve?!
        // nach knopfdruck auf show response Fehler hierdrin
        var handler = function () {
            id("header_header_" + req + "_" + j).value = ""; // wird dann in Alg. der request absendet nicht beachtet
            id("header_content_" + req + "_" + j).value = "";
            id("header_row_" + j).style.display = "none";
        }
        return handler;
    }

    if (bg().requests[req].header.length > 0) { // Header Arr kann leer sein
                

        function getHeaderAutoCompleteHandler(i) {
            var handler = function () {
                var header_name = id("header_header_" + req + "_" + i).value;
                var elements = getHeaderAutoCompleteElements(header_name);
                jQuery("input#header_content_" + req + "_" + i).autocomplete({ source: elements });
            }
            return handler;
        };

        for (j = 0; j < bg().requests[req].header.length; j++) {
                    
                    
            tr = document.createElement("tr");
            tr.id = "header_row_" + j;
            td = document.createElement("td");
            input = document.createElement("input");
            input.type = "text";
            name = bg().requests[req].header[j].name;
            if (name == "Cookie") {
                tr.style.display = "none";
                buildCookieEditor(bg().requests[req].header[j].value);
                input.type = "hidden";
                input.name = "header_header_" + req + "_" + j; 
                input.id = "header_header_" + req + "_" + j;
                input.value = name; // check if this is set to build cookie from table_r_cookie
                td.appendChild(input);
                td.colSpan = 3;
                tr.appendChild(td);
                id("table_r_header").appendChild(tr);
                continue;
            }
            input.name = "header_header_" + req + "_" + j; // besser ueber inidizes i,j
            input.id = "header_header_" +  req + "_" + j;
            input.value = name;
            /*if(isUserAgentHeader(name)) {
                input.setAttribute("readonly","readonly");
                input.setAttribute("style", "background-color:#FFCC99;");
            }*/
            td.appendChild(input);
            tr.appendChild(td);
            id("table_r_header").appendChild(tr);
            td = document.createElement("td");
            value = bg().requests[req].header[j].value;
            input = document.createElement("input");
            input.type = "text";
            input.name = "header_content_" + req + "_" + j;
            input.id = "header_content_" + req + "_" + j;
            input.value = value;
            input.setAttribute("style", "width:400px");
            /*if (isUserAgentHeader(name)) {
                input.onclick = userAgentHeaderMsg;
                input.setAttribute("readonly","readonly");
                input.setAttribute("style", "background-color:#FFCC99;width:400px;");
            } */
            input.onfocus = getHeaderAutoCompleteHandler(j);

            td.appendChild(input);
            tr.appendChild(td);

            td = document.createElement("td");
            tr.appendChild(td);
            button = document.createElement("input");
            button.type = "image";
        		button.src = "Delete.png";
        		button.alt = "Delete";
            button.onclick = getDelHeaderHandler(j);
            td.appendChild(button);
                    
        }
    }
    total_header = bg().requests[req].header.length; // spaeter koennen dynamisch header hinzukommen

    id("add_header_button").onclick = function () {
        if (jQuery.trim(id("add_header_name").value) == "") {
            return;
        }
        else {
            tr = document.createElement("tr");
            tr.id = "header_row_" + total_header;
            td = document.createElement("td");
            input = document.createElement("input");
            name = jQuery.trim(id("add_header_name").value);
            input.name = "header_header_" + req + "_" + total_header;
            input.id = "header_header_" + req + "_" + total_header;
            input.value = name;
            td.appendChild(input);
            tr.appendChild(td);
            td = document.createElement("td");
            value = jQuery.trim(id("add_header_value").value);
            input = document.createElement("input");
            input.name = "header_content_" + req + "_" + total_header;
            input.id = "header_content_" + req + "_" + total_header;
            input.value = value;
            input.setAttribute("style", "width:400px");
            input.onfocus = getHeaderAutoCompleteHandler(total_header);
            td.appendChild(input);
            tr.appendChild(td);

            td = document.createElement("td");
            tr.appendChild(td);
            button = document.createElement("input");
            button.type = "image";
        		button.src = "Delete.png";
        		button.alt = "Delete";
            button.onclick = getDelHeaderHandler(total_header);
            td.appendChild(button);
            tr.appendChild(td);

            id("table_r_header").appendChild(tr);
            total_header++;
            id("add_header_name").value = "";
            id("add_header_value").value = "";
        }
    };

    function getDelParamHandler(j) {
        // TODO: improve?!
        var handler = function () {
            id("param_name_" + req + "_" + j).value = "";
            id("param_value_" + req + "_" + j).value = "";
            id("param_row_" + j).style.display = "none";
        }
        return handler;
    };

    function getValueAutoCompleteHandler(i) {
        var handler = function () {
            var param_name = id("param_name_" + req + "_" + i).value;
            var xss_vectors;
            var sql_vectors;
            var elements = getParamAutoCompleteElements(param_name);
            if (id("make_suggestions_xss_check").checked == 1) {
                xss_vectors = getXSSVectorArray();
                elements = elements.concat(xss_vectors);
            }
            if (id("make_suggestions_sql_check").checked == 1) {
                sql_vectors = getSQLVectorArray();
                elements = elements.concat(sql_vectors);
            }
            //console.log(elements);
            jQuery("input#param_value_" + req + "_" + i).autocomplete({ source: elements });
        }
        return handler;
    };

   
    for (j = 0; j < bg().requests[req].params.length; j++) {

        tr = document.createElement("tr");
        tr.id = ("param_row_" + j);
        td = document.createElement("td");
        input = document.createElement("input");
        name = bg().requests[req].params[j].name;
        input.name = "param_name_" + req + "_" + j;
        input.id = "param_name_" + req + "_" + j;
        input.value = name;
        td.appendChild(input);
        tr.appendChild(td);
        
		  td = document.createElement("td");
        input = document.createElement("input");
        input.type = "checkbox";
        input.id = "param_name_" + req + "_" + j + "_URLencoding";
        input.name = "param_name_" + req + "_" + j + "_URLencoding";
		  if ("name_enc" in bg().requests[req].params[j]) {		  
		  		// do not encode (again), use encoding as given by user
     	  }
     	  else {
     	  		input.checked = "checked";	
     	  }
        td.appendChild(input);
        tr.appendChild(td);	        
        
        
        td = document.createElement("td");
        value = bg().requests[req].params[j].value;
        input = document.createElement("input");
        input.name = "param_value_" + req + "_" + j;
        input.id = "param_value_" + req + "_" + j;
        input.setAttribute("style", "width:400px");
        input.onfocus = getValueAutoCompleteHandler(j);
        input.value = value; 
        td.appendChild(input);
        tr.appendChild(td);

        
		  td = document.createElement("td");
        input = document.createElement("input");
        input.type = "checkbox";
        input.id = "param_value_" + req + "_" + j + "_URLencoding";
        input.name = "param_value_" + req + "_" + j + "_URLencoding";
		  if ("value_enc" in bg().requests[req].params[j]) {         
				// do not encode (again), use encoding as given by user        		
        		input_checked = "";
     	  }
     	  else {
     	  		input.checked = "checked";
     	  }
        td.appendChild(input);
        tr.appendChild(td);	
        
        td = document.createElement("td");
        tr.appendChild(td);
        button = document.createElement("input");
        button.type = "image";
        button.src = "Delete.png";
        button.alt = "Delete";
        button.onclick = getDelParamHandler(j);
        td.appendChild(button);
        
        
		                
        id("table_r_params").appendChild(tr);
	

    }

    total_params = bg().requests[req].params.length; // spaeter koennen dynamisch Parameter hinzukommen

    id("add_param_button").onclick = function () {
        var tr, td, input, button,name,value;

        if (jQuery.trim(id("add_param_name").value) == "") {
            return;
        }
        else {
            tr = document.createElement("tr");
            tr.id = ("param_row_" + total_params);
            td = document.createElement("td");
            input = document.createElement("input");
            name = jQuery.trim(id("add_param_name").value);
            input.name = "param_name_" + req + "_" + total_params;
            input.id = "param_name_" + req + "_" + total_params;
            input.value = name;
            td.appendChild(input);
            tr.appendChild(td);
            
            
				td = document.createElement("td");
	        	input = document.createElement("input");
	        	input.type = "checkbox";
	        	input.id = "param_name_" + req + "_" + total_params + "_URLencoding";
	        	input.name = "param_name_" + req + "_" + total_params + "_URLencoding";
	        	input.checked = "checked";
	        	td.appendChild(input);
	        	tr.appendChild(td);	                    
            
            
            td = document.createElement("td");
            value = jQuery.trim(id("add_param_value").value);
            input = document.createElement("input");
            input.name = "param_value_" + req + "_" + total_params;
            input.id = "param_value_" + req + "_" + total_params;
            input.setAttribute("style", "width:400px");
            input.onfocus = getValueAutoCompleteHandler(total_params);
            input.value = value;
            td.appendChild(input);
            tr.appendChild(td);


				td = document.createElement("td");
        		input = document.createElement("input");
        		input.type = "checkbox";
        		input.id = "param_value_" + req + "_" + total_params + "_URLencoding";
        		input.name = "param_value_" + req + "_" + total_params + "_URLencoding";
        		input.checked = "checked";
        		td.appendChild(input);
        		tr.appendChild(td);	


            td = document.createElement("td");
            tr.appendChild(td);
            button = document.createElement("input");
            button.type = "image";
            button.src = "Delete.png";
            button.alt = "Delete";
            button.onclick = getDelParamHandler(total_params);
            td.appendChild(button);
            
            

            id("table_r_params").appendChild(tr);
            total_params++;
            id("add_param_name").value = "";
            id("add_param_value").value = "";
        }
    };

    id("add_cookie_button").onclick = function () {
        // Falls noch kein Cookie existiert muss auch Eintrag in table_r_headers erstellt werden!
        var tr, td, input, button, name, value;

        if (jQuery.trim(id("add_cookie_name").value) == "") {
            return;
        } else {
            //id("table_r_cookie").style.display = "block";
            tr = document.createElement("tr");
            tr.id = "cookie_row_" + total_cookies;
            td = document.createElement("td");
            input = document.createElement("input");
            input.type = "hidden"; // speichere originalen Cookie Name um dieses entfernen zu koennen
            input.id = "cookie_" + total_cookies + "_orig_name";
            input.value = "";

            cookie_name = id("add_cookie_name").value;

            cookie_value = id("add_cookie_value").value;

            td.appendChild(input);
            input = document.createElement("input");
            input.type = "text";
            input.id = "cookie_" + total_cookies + "_name";
            input.value = cookie_name;
            td.appendChild(input);
            tr.appendChild(td);
            
            td = document.createElement("td");
	     		input = document.createElement("input");
	     		input.type = "checkbox";
	     		input.id = "cookie_" + total_cookies + "_name_URLencoding";
	     		input.name = "cookie_" + total_cookies + "_name_URLencoding";
	     		input.checked = "";
	     		td.appendChild(input);
	     		tr.appendChild(td);

            td = document.createElement("td");
            input = document.createElement("input");
            input.id = "cookie_" + total_cookies + "_value";
            input.value = cookie_value;
            input.setAttribute("style", "width:400px");
            input.onfocus = getCookieAutoCompleteHandler(total_cookies);
            td.appendChild(input);
            tr.appendChild(td);
            
            td = document.createElement("td");
	     		input = document.createElement("input");
	     		input.type = "checkbox";
	     		input.id = "cookie_" + total_cookies + "_value_URLencoding";
	     		input.name = "cookie_" + total_cookies + "_value_URLencoding";
	     		input.checked = "";
	     		td.appendChild(input);
	     		tr.appendChild(td);	 

            td = document.createElement("td");
            input = document.createElement("input");
            input.type = "image";
        		input.src = "Delete.png";
        		input.alt = "Delete";
            input.onclick = getDeleteCookieHandler(total_cookies);
            td.appendChild(input);
            tr.appendChild(td);
            id("table_r_cookie").appendChild(tr);
            id("table_r_cookie").style.display = "block";
            total_cookies++;

            if (total_cookies == 1) {
                // Zeile in header-Tabelle hinzufuegen, vorher gab es noch kein cookie
                // erstes Cookie erstellen fuktioniert noch nicht richtig
                tr = document.createElement("tr");
                input = document.createElement("input");
                td = document.createElement("td");
                tr.style.display = "none";
                input.type = "hidden";
                input.name = "header_header_" + req + "_" + total_header;
                input.id = "header_header_" + req + "_" + total_header;
                input.value = "Cookie"; // check if this is set to build cookie from table_r_cookie
                td.appendChild(input);
                td.colSpan = 3;
                tr.appendChild(td);
                id("table_r_header").appendChild(tr);
                total_header++;
            }
        }
        id("add_cookie_name").value = "";
        id("add_cookie_value").value = "";
    };

    var method_str = bg().requests[req].method.toUpperCase();
    id("request_method").value = method_str;

    if (method_str == "POST") {
        method_str = '<font color="#B80000">' + method_str + "</font>";
        id("table_r_header_descr").innerHTML = method_str + "&nbsp;HTTP Request Header:";
        id("table_r_params_descr").innerHTML = method_str + "&nbsp;HTTP Request Parameters:";
    }
    else {
        method_str = '<font color="#0000FF">' + method_str + "</font>";
        id("table_r_header_descr").innerHTML = method_str + "&nbsp;HTTP Request Header:";
        id("table_r_params_descr").innerHTML = method_str + "&nbsp;HTTP Request Parameters:";
    }

    id("add_sessionid_button").onclick = function () {
        // dynamisches menu zum hinzufuegen von sessionid namen
        var div, h2, h3, table;
        div = document.createElement("div");
        div.id = "new_sessionid_name_div";

        h2 = document.createElement("h2");
        h2.innerText = "Watch out for these SessionID names"

        h3 = document.createElement("h3");
        h3.innerText = "Known SessionID names:"

        table = document.createElement("table");
        table.id = "known_sessionid_table";
        table.style.borderColor = "#777777";
        table.style.borderWidth = "1px";
        table.style.borderStyle = "solid";

        function getRemoveSessIdHandler(i) {
            var handler = function () {
                bg().known_sessionid_names.splice(i, 1);
                document.location.reload();
            }
            return handler;
        }

        var str = "";
        var i,tr,td,str, del_button;
        for (i = 0; i < bg().known_sessionid_names.length; i++) {
            tr = document.createElement("tr");
            tr.id = "known_sessionid_row_" + i;
            td = document.createElement("td");
            str = bg().known_sessionid_names[i];
            font = document.createElement("font");
            font.color = "#ff8c00";
            font.innerHTML = str;
            td.appendChild(font);
            tr.appendChild(td);
            var del_button = document.createElement("input");
            del_button.type = "image";
        		del_button.src = "Delete.png";
        		del_button.alt = "Delete";
            del_button.onclick = getRemoveSessIdHandler(i);
            td = document.createElement("td");
            td.appendChild(del_button);
            tr.appendChild(td);
            table.appendChild(tr);
        }
		  var input, button1;
        input = document.createElement("input");
        input.type = "text";
        input.id = "add_sessionid_name_input";

        button1 = document.createElement("input");
        button1.type = "image";
        button1.src = "Add.png";
        button1.alt = "Add";
        button1.onclick = function () {
            var new_name = jQuery.trim(id("add_sessionid_name_input").value);
            if (new_name != "") {
                bg().known_sessionid_names.push(new_name);
                document.location.reload();
            }
            else {
                id("add_sessionid_div").removeChild(id("new_sessionid_name_div"));
                id("add_sessionid_button").style.display = "block";
            }
        };

        button2 = document.createElement("input");
        button2.type = "button";
        button2.value = "Cancel";
        button2.onclick = function () {
            id("add_sessionid_div").removeChild(id("new_sessionid_name_div"));
            id("add_sessionid_button").style.display = "block";
        };

        div.appendChild(h2);
        div.appendChild(h3);
        div.appendChild(table);
        div.appendChild(input);
        div.appendChild(button1);
        div.appendChild(button2);

        id("add_sessionid_div").appendChild(div);
        id("add_sessionid_button").style.display = "none";
    }

    id("show_response_button").onclick = function () {
        getHtmlResponseFromTampered();
    };

    id("radio_html_source").onclick = function () {
        id("response_html_source_div").style.display = "block";
        id("response_iframe_div").style.display = "none";
        id("response_header_div").style.display = "none";
        id("response_html_diff_div").style.display = "none";
    };

    id("radio_html_rendered").onclick = function () {
        // TODO: submitFormInIframe benutzen, damit seite komplett geladen wird?

        id("response_iframe_div").style.display = "block";
        id("response_html_source_div").style.display = "none";
        id("response_header_div").style.display = "none";
        id("response_html_diff_div").style.display = "none";
    };

    id("radio_response_header").onclick = function () {
        id("response_html_source_div").style.display = "none";
        id("response_iframe_div").style.display = "none";
        id("response_header_div").style.display = "block";
        id("response_html_diff_div").style.display = "none";
    };

    id("radio_html_diff").onclick = function () {
        id("response_html_source_div").style.display = "none";
        id("response_iframe_div").style.display = "none";
        id("response_header_div").style.display = "none";
        id("response_html_diff_div").style.display = "block";
    }

    id("open_response_new_tab_button").onclick = function () {
        /*************************************************************************************************************************************************************************
        * We need to submit a form with action = request_url and all forged parameters in the iframe to load the complete Document with all css and js
        * getHtmlResponseFromTampered gets only the server html response string, but due to same-origin-policy we cannot load additional css,js of the response in this extension
        *************************************************************************************************************************************************************************/
        var request = GET("r"); // index des requests in background datenstruktur
        var request_obj = {}; // neues request objekt kommt in die background datenstruktur
        var url = id("request_url").value;
        var method = id("request_method").value;
        var form = document.createElement("form");
        var html = document.createElement("html");

        form.target = "_blank";
        form.method = method.toUpperCase();
        form.action = url;
        form.id = "open_response_new_tab_form";

        var i;

        for (i = 0; i < total_header; i++) {
            // do we have cookies? then set them.
            if (jQuery.trim(id("header_header_" + request + "_" + i).value) == "Cookie") {
                setCookieFromInput();
            }
        }

        var param_arr = getEncodedParamArrayFromTampered();

        for (i = 0; i < param_arr.length; i++) {
            var input = document.createElement("input");
            input.type = "hidden";
            input.name = param_arr[i].name;
            input.value = param_arr[i].value;
            form.appendChild(input);
        }
        var script = document.createElement("script");
        script.src = "submitNewTabFormScript.js";
        html.appendChild(form);
        html.appendChild(script);
        id("form_submission_div").removeChild(id("form_submission_iframe"));
        var ifr = document.createElement("iframe");
        ifr.style.display = "none";
        ifr.id = "form_submission_iframe";
        id("form_submission_div").appendChild(ifr);
        var doc = frames["form_submission_iframe"].document;
        var content_container = document.createElement("div");
        content_container.appendChild(html);
		  checkBlockingModeBeforeSend();
		  registerRequestHeaders(getHeaderArrayFromTampered());        
        doc.open();
        doc.write(content_container.innerHTML);        
        doc.close();
        console.log("Writing auto-submit form");
        setTimeout(function() {checkBlockingModeAfterSend();bg().tamperedHeaders = null;}, 1000); // allow the tab to load within 1000 ms, need to be improved?
        // TODO: clean up, delete ifr after everything is done
        //saveRequest(); // not necessary, webRequest API captures this
    }
}
